﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office.Server.UserProfiles;
using System.Web;

namespace SPPivotViewer.HttpHandler.Internal
{
    public class SPProfileUserCollectionFactory
    {
        public Collection MakeCollection(CollectionRequestContext context, string collectionFileName, SPListCollectionParam param)
        {
            Collection colReturn = new Collection();
            colReturn.Name = "User Profiles";
            SPContext contextSharePoint = SPContext.Current;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(contextSharePoint.Site.ID))
                {
                    using (SPWeb web = site.OpenWeb(contextSharePoint.Web.ID))
                    {
                        List<Facet> lstFacet = new List<Facet>();
                        SPUserCollection spuc = web.AllUsers;
                        SPServiceContext serviceContext = SPServiceContext.GetContext(site);
                        // Initialize user profile config manager object 
                        UserProfileManager upm = new UserProfileManager(serviceContext);
                        
                        foreach (SPUser user in  spuc)
                        {
                            lstFacet.Clear();
                            //Create user sample string sAccount = "mydomain\\myalias"; 
                            if (!upm.UserExists(user.LoginName))
                                continue;
                            //To set prop values on user profile 
                            UserProfile u = upm.GetUserProfile(user.LoginName);
                            string strPictureUrl = "";
                            ProfileSubtypePropertyManager properties = u.Properties;
                            foreach (ProfileSubtypeProperty psp in properties)
                            {
                                List<string> lstFilter = new List<string>();
                                List<string> lstInfos = new List<string>();
                                if (param.Facets != null)
                                    lstFilter.AddRange(param.Facets);
                                if (param.Infos != null)
                                    lstInfos.AddRange(param.Infos);

                                if (psp.Name != "PictureURL" && ((!lstFilter.Contains(psp.DisplayName) && lstFilter.Count > 0) && (!lstInfos.Contains(psp.DisplayName) && lstInfos.Count > 0)))
                                    continue;

                                if (psp.Name == "PictureURL")
                                {
                                    object PictureUrlValue = u[psp.Name].Value;
                                    strPictureUrl = u[psp.Name].Value == null ? web.Url + "/_layouts/images/O14_person_placeHolder_192.png" : u[psp.Name].Value.ToString();
                                }
                                else
                                {
                                    FacetType typeFacet;
                                    object valueFacet = null;
                                    if (!getFacetTypeFromField(psp, out typeFacet))
                                        continue;
                                    if (!getValueFromItem(u, psp, upm, typeFacet, out valueFacet))
                                        continue;
                                    object UserProfileValue = valueFacet;
                                    string strFacetName = (psp.DisplayName.ToLower() == "name") ? "[" + psp.DisplayName + "]" : psp.DisplayName;
                                    if (strFacetName.ToLower() == "description")
                                        strFacetName = "["+strFacetName +"]";
                                    if (UserProfileValue != null)
                                    {
                                        Facet facet = new Facet(strFacetName, typeFacet, UserProfileValue);
                                        if (lstFilter.Count > 0 && !lstFilter.Contains(psp.DisplayName))
                                            facet.ShowInFacetPane = false;
                                        if (lstInfos.Count > 0 && !lstInfos.Contains(psp.DisplayName))
                                            facet.ShowInInfoPane = false;

                                        lstFacet.Add(facet);
                                    }
                                }
                            }
                            string strUrl = "";
                            using (SPSite PersonalSite = u.PersonalSite)
                            {
                                strUrl = PersonalSite == null ? u.PersonalUrl.AbsoluteUri : PersonalSite.Url;
                            }
                            colReturn.AddItem(u.DisplayName, strUrl, null, new ItemImage(new Uri(strPictureUrl)), lstFacet.ToArray());

                        }
                    }

                }
            });
            return colReturn;

        }
        private bool getValueFromItem(UserProfile u, ProfileSubtypeProperty psp,UserProfileManager upm, FacetType typeFacet, out object valueFacet)
        {
            valueFacet = null;
            if (typeFacet == FacetType.DateTime)
            {
                return getFacetValueToDate(u, psp, out  valueFacet);
            }
            if (typeFacet == FacetType.Text)
            {
                return getFacetValueToText(u, psp,upm, out  valueFacet);
            }
            if (typeFacet == FacetType.Link)
            {
                return getFacetValueToLink(u, psp, out  valueFacet);
            }
            if (typeFacet == FacetType.Number)
            {
                return getFacetValueToNumber(u, psp, out  valueFacet);
            }
            return false;
        }

        private bool getFacetValueToNumber(UserProfile u, ProfileSubtypeProperty psp, out object valueFacet)
        {
            valueFacet = null;
            if (u[psp.Name].Value == null)
                return false;
            int iValue;
            bool biValue = int.TryParse(u[psp.Name].Value.ToString(), out iValue);

            float fValue;
            bool bfValue = float.TryParse(u[psp.Name].Value.ToString(), out fValue);

            if (!bfValue && !biValue)
                return false;


            if (fValue == iValue)
                valueFacet = iValue;
            else
                valueFacet = fValue;
            return true;
        }

        private bool getFacetValueToLink(UserProfile u, ProfileSubtypeProperty psp, out object valueFacet)
        {
            valueFacet = null;
            if (u[psp.Name].Value == null)
                return false;
            FacetHyperlink fh = new FacetHyperlink(psp.DisplayName, u[psp.Name].Value.ToString());
            if (fh.Name == null || fh.Url == null)
                return false;
            valueFacet = fh;
            return true;
        }

        private bool getFacetValueToText(UserProfile u, ProfileSubtypeProperty psp, UserProfileManager upm, out object valueFacet)
        {
            valueFacet = null;
            string strType = psp.TypeProperty.CoreProperty.Type;
            if (u[psp.Name].Value == null)
                return false;
            if (strType == "Person")
            {
                
                UserProfile up= upm.GetUserProfile(u[psp.Name].Value.ToString());

                valueFacet = up.DisplayName;
            }
            else
                valueFacet = u[psp.Name].Value;
            if (valueFacet.ToString() == string.Empty)
                return false;
            else
                return true;
        }

        private bool getFacetValueToDate(UserProfile u, ProfileSubtypeProperty psp, out object valueFacet)
        {
            valueFacet = null;
            if (u[psp.Name].Value == null)
                return false;
            DateTime? dtValue = u[psp.Name].Value as DateTime?;
            if (dtValue == null || !dtValue.HasValue)
                return false;
            valueFacet = dtValue.Value;
            return true;

        }

        private bool getFacetTypeFromField(ProfileSubtypeProperty psp, out FacetType outFacet)
        {
            outFacet = FacetType.Text;
            bool bReturn = false;
            string strType= psp.TypeProperty.CoreProperty.Type;
            if (strType == "date")
            {
                outFacet = FacetType.DateTime;
                bReturn = true;
            }

            if (strType == "Person" || strType == "string (Single Value)" || strType == "HTML" || strType == "string (Multi Value)" || strType == "Email" || strType == "timezone")
            {
                outFacet = FacetType.Text;
                bReturn = true;
            }
            //if (strType == "URL")
            //{
            //    outFacet = FacetType.Link;
            //    bReturn = true;
            //}
            if (strType== "integer")
            {
                outFacet = FacetType.Number;
                bReturn = true;
            }

            return bReturn;
        }
    }
}
